package com.basic.common.utils;

import com.alibaba.fastjson.parser.Feature;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;
import net.sf.json.util.PropertySetStrategy;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Json工具类
 * 
 * @author 
 * 
 */
public class JsonUtils {

    public static String jsonFormatter(String uglyJsonString) {
        //校验格式用 不对会抛异常
        JSONObject.fromObject(uglyJsonString);
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        JsonParser jp = new JsonParser();
        JsonElement je = jp.parse(uglyJsonString);
        String prettyJsonString = gson.toJson(je);
        return prettyJsonString;
    }

    /**
     * <i>弃用此方法，改用json2Object</i>
     * 
     * @param jsonString
     * @return
     */
    @Deprecated
    public static JSONObject json2Obj(String jsonString) {
        return JSONObject.fromObject(jsonString);
    }

    /**
     * json转jsonObject
     * 
     * @param jsonArrayString
     * @return
     */
    @Deprecated
    public static JSONArray array2Obj(String jsonArrayString) {
        if (StringUtils.isBlank(jsonArrayString)) {
            return null;
        }
        String[] dateFormats = new String[] { "yyyy-MM-dd HH:mm:ss" };
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        return JSONArray.fromObject(jsonArrayString);
    }

    /**
     * json转Object[]
     * 
     * @return
     */
    @Deprecated
    public static Object[] array2ObjArray(String jsonArrayString) {
        if (StringUtils.isBlank(jsonArrayString)) {
            return null;
        }
        String[] dateFormats = new String[] { "yyyy-MM-dd HH:mm:ss" };
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        return JSONArray.fromObject(jsonArrayString).toArray();
    }

    /**
     * json转List
     * 
     * @return
     */
    public static <T> List<T> array2List(String jsonArrayString, Class<T> type) {
        if (StringUtils.isBlank(jsonArrayString)) {
            return null;
        }
        return com.alibaba.fastjson.JSONArray.parseArray(jsonArrayString, type);
    }

    /**
     * JSONArray转List
     * 
     * @return
     */
    @SuppressWarnings("unchecked")
    @Deprecated
    public static <T> List<T> array2List(JSONArray jsonArray, Class<T> type) {
        if (jsonArray == null || jsonArray.size() == 0) {
            return null;
        }
        return (List<T>) JSONArray.toCollection(jsonArray, type);
    }

    /**
     * <i>弃用此方法，改用json2Object</i>
     * 
     * 
     * @param json
     * @param clazz
     * @return
     */
    @Deprecated
    public static <T> T json2Obj(String json, Class<T> clazz) {
        return json2Obj(json, clazz, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * json转成Object对象
     * 
     * fastjson类处理
     * 
     * @param json
     * @param json
     * @return
     */
    public static com.alibaba.fastjson.JSONObject json2Object(String json) {
        return com.alibaba.fastjson.JSONObject.parseObject(json, Feature.OrderedField);
    }

    /**
     * json转成Object对象
     * 
     * fastjson类处理
     * 
     * @param json
     * @param sort
     * @return
     */
    public static com.alibaba.fastjson.JSONObject json2Object(String json, boolean sort) {
        if (!sort) {
            json2Object(json);
        }
        return com.alibaba.fastjson.JSONObject.parseObject(json);
    }

    /**
     * json转成Object对象
     * 
     * fastjson类处理
     * 
     * @param json
     * @param clazz
     * @return
     */
    public static <T> T json2Object(String json, Class<T> clazz) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        com.alibaba.fastjson.JSONObject jsonObj = com.alibaba.fastjson.JSON.parseObject(json);
        return com.alibaba.fastjson.JSONObject.toJavaObject(jsonObj, clazz);
    }

    /**
     * json转成Object对象，并class中忽略不存在的属性
     * 
     * fastjson类处理
     * 
     * @param json
     * @param clazz
     * @return
     */
    public static <T> T json2ObjectIgnored(String json, Class<T> clazz) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        return com.alibaba.fastjson.JSON.parseObject(json, clazz);
    }

    /**
     * json转成成Object对象,带日期格式处理
     * 
     * @param json
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T json2Obj(String json, Class<T> clazz, String dateFormat) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        JSONObject jsonObject = JSONObject.fromObject(json);
        String[] dateFormats = new String[] { dateFormat };
        JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(dateFormats));
        return (T) JSONObject.toBean(jsonObject, clazz);
    }

    /**
     * 
     * @param json
     * @param clazz
     *            object类名
     * @param classMap
     *            object类的泛型
     * @return
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static <T> T json2Obj(String json, Class<T> clazz, Map<String, Class> classMap) {
        JSONObject jsonObject = JSONObject.fromObject(json);
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setRootClass(clazz);
        jsonConfig.setClassMap(classMap);
        jsonConfig.setPropertySetStrategy(new PropertySetStrategy() {

            @Override
            public void setProperty(Object o, String string, Object o1) throws JSONException {
                try {
                    PropertySetStrategy.DEFAULT.setProperty(o, string, o1);
                } catch (Exception ex) {
                    // ignore
                }
            }
        });
        return (T) JSONObject.toBean(jsonObject, jsonConfig);
    }

    /**
     * java对象转json字符串
     * 
     * @param obj
     */
    public static String obj2Json(Object obj) {
        return obj2Json(obj, 0);
    }

    /**
     * java对象转json字符串
     * 
     * @param obj
     * @param mode
     *            转换模式（0-全部属性，1-非空属性，2-非空串属性）
     */
    public static String obj2Json(Object obj, int mode) {
        if (obj == null) {
            return null;
        }
        ObjectMapper objectMapper = new ObjectMapper();
        switch (mode) {
        case 0:
            objectMapper.setSerializationInclusion(Inclusion.ALWAYS);
            break;
        case 1:
            objectMapper.setSerializationInclusion(Inclusion.NON_NULL);
            break;
        case 2:
            objectMapper.setSerializationInclusion(Inclusion.NON_EMPTY);
            break;
        default:
            objectMapper.setSerializationInclusion(Inclusion.ALWAYS);
            break;
        }
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        String json = null;
        try {
            json = objectMapper.writeValueAsString(obj);
        } catch (JsonGenerationException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return json;
    }

    public static com.alibaba.fastjson.JSONObject obj2JsonObject(Object obj) {
        return json2Object(obj2Json(obj, 2));
    }

    /**
     * 将json对象转换成Map
     * 
     * @param jsonData
     *            json对象
     * @return Map对象
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> toMap(String jsonData) {
        JSONObject jsonObject = JSONObject.fromObject(jsonData);
        Map<String, String> result = new LinkedHashMap<String, String>();
        Iterator<String> iterator = jsonObject.keys();
        String key = null;
        String value = null;
        while (iterator.hasNext()) {
            key = iterator.next();
            value = jsonObject.getString(key);
            result.put(key, value);
        }
        return result;
    }

    /**
     * 将json对象转换成Map
     * 
     * @param jsonData
     *            json对象
     * @return Map对象
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> toObjectMap(String jsonData) {
        JSONObject jsonObject = JSONObject.fromObject(jsonData);
        Map<String, Object> result = new LinkedHashMap<String, Object>();
        Iterator<String> iterator = jsonObject.keys();
        String key = null;
        Object value = null;
        while (iterator.hasNext()) {
            key = iterator.next();
            value = jsonObject.get(key);
            result.put(key, value);
        }
        return result;
    }

    /**
     * 将json对象转换成Map
     * 
     * @param jsonObject
     *            json对象
     * @return Map对象
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> toMap(JSONObject jsonObject) {
        Map<String, String> result = new HashMap<String, String>(16);
        Iterator<String> iterator = jsonObject.keys();
        String key = null;
        String value = null;
        while (iterator.hasNext()) {
            key = iterator.next();
            value = jsonObject.getString(key);
            result.put(key, value);
        }
        return result;
    }
}
